package operation;

import abbot.finder.*;
import abbot.finder.matchers.ClassMatcher;
import abbot.tester.*;
import abbot.tester.Robot;
import abbot.util.AWTFixtureHelper;
import com.supermap.data.Datasource;
import robotCross.CrossRobot;
import util.Info;
import util.ScreenImage;

import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;

/**
 * Created by hanyz on 2016/9/6.
 */
public class Operation {
	public static AWTFixtureHelper helper = null;
	public static abbot.tester.Robot robot = null;
	public static ArrayList<Datasource> datasources = new ArrayList();

	//Operation很多操作类似，区别在于查找控件的容器不同。将容器作为基类成员变量，子类需要根据需要初始化对应的container。
	public Container container;

	public Operation() {
	}

	public Operation(Container container) {
		this.container = container;
	}

	public Container getContainer() {
		return container;
	}

	public void setContainer(Container container) {
		this.container = container;
	}

	public void closeContainer() {
		if (container != null) {
			new WindowTester().actionClose(container);
		}
	}

	/**
	 * 释放未经过UI打开的数据源
	 */
	public static void releaseDatasources() {
		try {
			for (Iterator<Datasource> it = Operation.datasources.iterator(); it.hasNext(); ) {
				Datasource datasource = it.next();
				if (datasource != null) {
					datasource.close();
				}
				it.remove();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public Component searchComponent(Matcher matcher) throws ComponentNotFoundException, MultipleComponentsFoundException {
		Component component = null;
		component = new BasicFinder() {
			@Override
			protected void findMatches(Hierarchy h, Matcher m, Component c, Set found) {
				if (c.isVisible() && c.isEnabled()) {
					super.findMatches(h, m, c, found);
				}
			}
		}.find(container, matcher);
		return component;
	}

	public void clickComponent(Component component) {
		Operation.robot.click(component);
	}

	public Object clickComponent(Matcher matcher) throws ComponentNotFoundException, MultipleComponentsFoundException {
		Component component = this.searchComponent(matcher);
		if (component != null) {
			this.clickComponent(component);
			Operation.robot.delay(500);
		}
		return component;
	}

	public Object getComponentValue(Component component, String valueDescription) {
		Object value = null;
		return value;
	}

	// TODO: 2017/3/4 直接用string做item，数据源那种有图片的comboBox可能不支持。
	public void setComboBoxSelectedItem(Matcher matcher, String item) throws ComponentNotFoundException, MultipleComponentsFoundException {
		if (container == null || matcher == null) return;
		Component component = this.searchComponent(matcher);
		if (component != null && component instanceof JComboBox) {
			new JComboBoxTester().actionSelectItem(component, item);
		}
	}

	public void setComboBoxSelectedIndex(Matcher matcher, int index) throws ComponentNotFoundException, MultipleComponentsFoundException {
		if (container == null || matcher == null) return;
		Component component = this.searchComponent(matcher);
		if (component != null && component instanceof JComboBox) {
			new JComboBoxTester().actionSelectIndex(component, index);
		}
	}

	/**
	 * 直接往combox中输入内容
	 * @param matcher
	 * @param value
	 */
	public void editComboBox(Matcher matcher, String value) throws ComponentNotFoundException, MultipleComponentsFoundException {
		if (container == null || matcher == null) return;
		Component component = this.searchComponent(matcher);
		if (component != null && component instanceof JComboBox && ((JComboBox) component).isEditable()) {
			JTextField jTextField = (JTextField) ((JComboBox) component).getEditor().getEditorComponent();
			new JTextComponentTester().actionEnterText(jTextField, value);
			//new Robot().keyPress(KeyEvent.VK_ENTER);
		}
		robot.delay(1000);
	}

	/**
	 * 设置Spinner中的内容
	 *
	 * @param matcher
	 * @param value
	 */
	public void setSpinnerValue(Matcher matcher, String value) throws ComponentNotFoundException, MultipleComponentsFoundException {
		if (container == null || matcher == null) return;
		Component component = this.searchComponent(matcher);
		if (component != null && component instanceof JSpinner) {
			new JSpinnerTester().actionSetValue(component, value);
			new Robot().keyPress(KeyEvent.VK_ENTER);
		}
		robot.delay(1000);
	}

	/**
	 * 设置JTextField中的值
	 *
	 * @param matcher
	 * @param value
	 */
	public void editTextField(Matcher matcher, String value) throws ComponentNotFoundException, MultipleComponentsFoundException {
		if (container == null || matcher == null) return;
		Component component = this.searchComponent(matcher);
		if (component != null && component instanceof JTextField) {
			new JTextComponentTester().actionEnterText(component, value);
		}
		robot.delay(1000);
	}

	public void setTextComponentValue(Matcher matcher, String value) throws ComponentNotFoundException, MultipleComponentsFoundException {
		if (container == null || matcher == null) return;
		Component component = this.searchComponent(matcher);
		if (component != null && component instanceof JTextComponent) {
			new JTextComponentTester().actionEnterText(component, value);
		}
	}

	public void clickMenuItem(String menuPath) {
		new ComponentTester().actionSelectMenuItem(container, menuPath);
	}

	public void clickRightButtonMenuItem(String menuPath) {
		new CrossRobot().clickRightMouse();
		Robot.delay(500);
		new ComponentTester().actionSelectMenuItem(container, menuPath);
	}

	public void selectListItem(String item) throws ComponentNotFoundException, MultipleComponentsFoundException {
		this.selectListItem(new ClassMatcher(JList.class), item);
	}

	public void selectListIndex(int index) throws ComponentNotFoundException, MultipleComponentsFoundException {
		this.selectListIndex(new ClassMatcher(JList.class), index);
	}

	public void selectListItem(Matcher matcher, String item) throws ComponentNotFoundException, MultipleComponentsFoundException {
		Component component = this.searchComponent(matcher);
		if (component != null && component instanceof JList) {
			new ListOperation((JList) component).selectItem(item);
		}
	}

	public void selectListIndex(Matcher matcher, int index) throws ComponentNotFoundException, MultipleComponentsFoundException {
		Component component = this.searchComponent(matcher);
		if (component != null && component instanceof JList) {
			new ListOperation((JList) component).selectIndex(index);
		}
	}

	public void saveAsPicture(String path) {
		try {
			saveAsPicture(container, path);
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void saveAsPicture(final Container c, final String path) throws InvocationTargetException, InterruptedException {
		try {
			File file = new File(path);
			File parentDir = file.getParentFile();
			if (!parentDir.exists()) {
				parentDir.mkdirs();
			}
			BufferedImage image = ScreenImage.createImage(c);
			ScreenImage.writeImage(image, path);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
